﻿using System;
using System.ComponentModel;
using System.Collections.Generic;

using EagleJournalBE.Util;

namespace EagleJournalBE.Database
{
    public abstract class TableBase
    {
        private     string              primaryKey;
        public      string              PrimaryKey
        {
            get { return this.primaryKey; }
        }

        private     string              tableName;
        public      string              TableName
        {
            get { return this.tableName; }
        }

        private     List<string>        columns;
        public      List<string>        TableColumns
        {
            get { return this.columns; }
        }

        private     List<List<object>>  data;
        public      List<List<object>>  TableData
        {
            get { return this.data; }
        }

        /// <summary>
        /// Creates a table for binding to the database.
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columns"></param>
        public              TableBase   (string PK, string tableName, List<string> columns)
        {
            this.primaryKey = PK;
            this.tableName  = tableName;

            this.columns    = columns;
            this.data       = new List<List<object>>();
        }

        /// <summary>
        /// Reloads the value of the table.
        /// </summary>
        public void         Refresh     ()
        {
            Logger.WriteInfo(LoggingType.INFO, this, "Refreshing table...");

            this.data = DatabaseConnector.ReadQuery(this.tableName, string.Empty, this.columns);

            Logger.WriteInfo(LoggingType.INFO, this, "Refresh complete!");
        }
        /// <summary>
        /// Filters the data this table currently has.
        /// </summary>
        public void         Filter      (string query)
        {
            this.data = DatabaseConnector.ReadQuery(this.tableName, query, this.columns);
        }

        /// <summary>
        /// Adds a data row to the list.
        /// </summary>
        /// <param name="primaryKey">The PK of the row.</param>
        /// <param name="data">The data of the row (excluding the PK).</param>
        public virtual void Create      (int primaryKey, List<object> data)
        {
            Logger.WriteInfo(LoggingType.INFO, this, "Creating row in table " + this.tableName);

            Dictionary<string, object> row = new Dictionary<string, object>();

            if (data.Count != this.columns.Count)
                throw new InvalidOperationException("Column count is not equal to data count!");

            for (int i = 0; i < this.columns.Count; i++)
                row.Add(this.columns[i], data[i]);

            DatabaseConnector.InstQuery(this.tableName, row);

            this.Refresh();

            Logger.WriteInfo(LoggingType.INFO, this, "Create complete!");
        }
        /// <summary>
        /// Removes a data row in the list.
        /// </summary>
        /// <param name="primaryKey">The PK of the row.</param>
        public virtual void Remove      (int primaryKey)
        {
            Logger.WriteInfo(LoggingType.INFO, this, "Deleting row with PK " + primaryKey);

            DatabaseConnector.TrshQuery(this.tableName, string.Format("{0}= {1}", this.primaryKey, primaryKey));

            this.Refresh();

            Logger.WriteInfo(LoggingType.INFO, this, "Delete complete!");
        }
        /// <summary>
        /// Updates a data row in the list.
        /// </summary>
        /// <param name="primaryKey">The PK of the row.</param>
        /// <param name="data">The data of the row (excluding the PK).</param>
        public virtual void Update      (int primaryKey, List<object> data)
        {
            Logger.WriteInfo(LoggingType.INFO, this, "Updating row with PK " + primaryKey);

            Dictionary<string, object> row = new Dictionary<string, object>();

            if (data.Count != this.columns.Count)
                throw new InvalidOperationException("Column count is not equal to data count!");

            for (int i = 0; i < this.columns.Count; i++)
                row.Add(this.columns[i], data[i]);

            DatabaseConnector.EditQuery(this.tableName, string.Format("{0} = {1}", this.primaryKey, primaryKey), row);

            this.Refresh();

            Logger.WriteInfo(LoggingType.INFO, this, "Update complete!");
        }
    }
}
